package com.usian.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usian.common.constants.NewsConstant;
import com.usian.model.admin.dtos.NewsAuthDto;
import com.usian.model.base.BaseServiceImpl;
import com.usian.model.common.dtos.PageResponseResult;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.dtos.WmNewsPageReqDto;
import com.usian.model.media.pojos.WmMaterial;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsMaterial;
import com.usian.model.media.pojos.WmUser;
import com.usian.model.media.vos.WmNewsVo;
import com.usian.utils.threadlocal.ThreadLocalUtils;
import com.usian.wemedia.mapper.MediaUserMapper;
import com.usian.wemedia.mapper.WmNewsMapper;
import com.usian.wemedia.service.NewsMaterialService;
import com.usian.wemedia.service.WmMaterialService;
import com.usian.wemedia.service.WmNewsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsServiceImpl extends BaseServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
    @Value("${fdfs.url}")
    private String baseUrl;
    @Autowired
    private WmMaterialService materialService;
    @Autowired
    private NewsMaterialService newsMaterialService;
    @Autowired
    private KafkaTemplate kafkaTemplate;
    @Autowired
    private MediaUserMapper userMapper;

    @Override
    public ResponseResult findAll(WmNewsPageReqDto dto) {
        if (dto == null) return paramError;
        Integer userId = ThreadLocalUtils.getUserId();
        if (userId == null) return needLogin;
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(dto.getStatus() != null, WmNews::getStatus, dto.getStatus());
        wrapper.like(StringUtils.isNotBlank(dto.getKeyword()), WmNews::getTitle, dto.getKeyword());
        wrapper.eq(dto.getChannelId() != null, WmNews::getChannelId, dto.getChannelId());
        wrapper.eq(WmNews::getUserId, userId);
        wrapper.orderByDesc(WmNews::getCreatedTime);
        if (dto.getBeginPubDate() != null && dto.getEndPubDate() != null)
            wrapper.between(WmNews::getCreatedTime, dto.getBeginPubDate(), dto.getEndPubDate());
        return getPageData(dto, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult saveNews(WmNewsDto wmNews) {
        if (wmNews == null || StringUtils.isBlank(wmNews.getTitle()) || StringUtils.isBlank(wmNews.getContent()) || wmNews.getType() == null)
            return paramError;
        Integer userId = ThreadLocalUtils.getUserId();
        if (userId == null) return needLogin;
        //在新闻表里插入新闻数据
        WmNews news = new WmNews();
        BeanUtils.copyProperties(wmNews, news);
        news.setUserId(userId);
        news.setCreatedTime(new Date());
        news.setEnable((short) 1);
        //封面类型处理
        List<String> faceImages = wmNews.getImages();//放的是封面图的路劲
        if (faceImages != null && faceImages.size() != 0) {
            StringBuffer buffer = new StringBuffer();
            faceImages = faceImages.stream().map(m -> {
                m = m.replace(baseUrl, "");
                buffer.append(m).append(",");
                return m;
            }).collect(Collectors.toList());
            String s = buffer.toString().substring(0, buffer.toString().length() - 1);
            news.setImages(s);
        }
        String content = wmNews.getContent();//从内容获取图片，确定封面图的类型
        JSONArray array = JSON.parseArray(content);
        List<String> contentImages = new ArrayList<>();
        for (Object ele : array) {
            JSONObject object = JSON.parseObject(ele.toString());
            String type = object.getString("type");
            if (type.equals("image")) {
                String imagePath = object.getString("value").replace(baseUrl, "");
                contentImages.add(imagePath);
            }
        }
        if (wmNews.getType() == -1) {//说明前端在提交新闻的时候，对封面类型选择了自动
            int temp;
            StringBuilder tempImages = new StringBuilder();
            if (contentImages.size() > 0) {
                if (contentImages.size() > 2) {
                    temp = 3;
                    for (int i = 0; i < 3; i++) tempImages.append(contentImages.get(i)).append(",");
                } else {
                    temp = 1;
                    tempImages.append(contentImages.get(0)).append(",");
                }
            } else {
                temp = 0;
            }
            String s = tempImages.toString();
            if (s.endsWith(",")) {//a,b,
                s = s.substring(0, s.length() - 1);
            }
            news.setType((short) temp);
            news.setImages(s);
        }
        //新增文章
        if (wmNews.getId() == null) {
            save(news);
        } else {
            updateById(news);
            //批量删除素材和新闻的中间关系
            newsMaterialService.remove(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, news.getId()));
        }
        //在新闻和素材的中间表插入数据
        List<WmNewsMaterial> faceData = saveNewsMaterialRelations(news, faceImages, 1);//保存封面图和新闻的关系数据
        List<WmNewsMaterial> contentData = saveNewsMaterialRelations(news, contentImages, 0);//保存内容图和新闻的关系数据
        faceData.addAll(contentData);
        newsMaterialService.saveBatch(faceData);
        kafkaTemplate.send(NewsConstant.WM_NEWS_AUTO_SCAN_TOPIC,news.getId()+"");
        return success;
    }

    @Override
    public ResponseResult findWmNewsById(Long id) {
        if (id == null) return paramError;
        WmNews news = getById(id);
        return success(news);
    }

    @Override
    @Transactional
    public ResponseResult delNews(Long id) {
       return temp(id);
    }

    public ResponseResult temp(Long id){
        if (id == null) return paramError;
        Integer userId = ThreadLocalUtils.getUserId();
        if (userId == null) return needLogin;
        //删除新闻数据
        removeById(id);
        //删除中间数据
        newsMaterialService.remove(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, id));
        return success;
    }

    @Override
    public ResponseResult downOrUp(Long id, Short enable) {
        if (id == null || enable == null || (enable != 0 && enable != 1)) return paramError;
        Integer userId = ThreadLocalUtils.getUserId();
        if (userId == null) return needLogin;
        update(Wrappers.<WmNews>lambdaUpdate().eq(WmNews::getId, id).eq(WmNews::getUserId, userId).set(WmNews::getEnable, enable));
        WmNews news = getById(id);
        //讲文章id和上下架状态发送给C端平台进行上下架状态同步
        Map<String,Number> map = new HashMap<>();
        map.put("articleId",news.getArticleId());
        map.put("enable",enable);
        kafkaTemplate.send(NewsConstant.WM_NEWS_UP_OR_DOWN,JSON.toJSONString(map));
        return success;
    }

    @Override
    public List<Long> findRelease() {
        List<WmNews> list = list(Wrappers.<WmNews>lambdaQuery().eq(WmNews::getStatus, 8).or().eq(WmNews::getStatus,4).lt(WmNews::getPublishTime,new Date()));//lessthen
        List<Long> resultList = list.stream().map(WmNews::getId).collect(Collectors.toList());
        return resultList;
    }

    /**
     * 查询待人工审核的数据
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findList(NewsAuthDto dto) {
        dto.setPage((dto.getPage()-1)*dto.getSize());
        if (StringUtils.isNotBlank(dto.getTitle()))dto.setTitle("%"+dto.getTitle()+"%");
        List<WmNewsVo> list = baseMapper.findListAndPage(dto);
        //这个接口提供给后台管理平台（pc平台）
        int count = baseMapper.findListCount(dto);
        ResponseResult responseResult = new PageResponseResult(dto.getPage(),dto.getSize(),count);
        responseResult.setData(list);
        return responseResult;
    }

    /**
     * 后台审核人员审核具体的某个新闻，根据id查询新闻详情
     * @param id
     * @return
     */
    @Override
    public WmNewsVo findWmNewsVo(Long id) {
        WmNews wmNews = getById(id);
        WmUser wmUser = null;
        if(wmNews!=null && wmNews.getUserId() != null){
            wmUser = userMapper.selectById(wmNews.getUserId());
        }
        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNews,wmNewsVo);
        if(wmUser != null){
            wmNewsVo.setAuthorName(wmUser.getName());
        }
        return wmNewsVo;
    }

    private List<WmNewsMaterial> saveNewsMaterialRelations(WmNews news, List<String> images, Integer type) {
        ////根据图片路劲的集合查询图片对象
        List<WmMaterial> faceMaterial = materialService.list(Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl, images));
        List<Integer> faceIds = faceMaterial.stream().map(m -> m.getId()).collect(Collectors.toList());
        List<WmNewsMaterial> saveList = new ArrayList<>();
        for (int i = 0; i < faceIds.size(); i++) {
            WmNewsMaterial newsMaterial = new WmNewsMaterial();
            newsMaterial.setMaterialId(faceIds.get(i));
            newsMaterial.setNewsId(news.getId());
            newsMaterial.setType(type.shortValue());
            newsMaterial.setOrd((short) (i + 1));
            saveList.add(newsMaterial);
        }
        return saveList;
    }
}
